# from django.utils.deprecation import MiddlewareMixin
# from rest_framework.authentication import get_authorization_header
# from rest_framework import exceptions
# import jwt
# from django.conf import settings
# from django.contrib.auth import get_user_model
# from django.http.response import JsonResponse
# from rest_framework.status import HTTP_403_FORBIDDEN
# from jwt.exceptions import ExpiredSignatureError
# from django.contrib.auth.models import AnonymousUser
#
# OAUser = get_user_model()
#
# class LoginCheckMiddleware(MiddlewareMixin):
#     keyword = 'JWT'
#
#     def __init__(self, *args, **kwargs):
#         super().__init__(*args, **kwargs)
#         # 对于那些不需要登录就能访问的接口，可以写在这里
#         self.white_list = ['/auth/login', '/staff/active']
#
#     def process_view(self,request, view_func, view_args, view_kwargs):
#         if request.path in self.white_list:
#             # AnonymousUser为匿名用户
#             request.user = AnonymousUser()
#             request.auth = None
#             # 继续向后处理
#             return None
#         # request HttpRequest对象 也是django内置的对象
#         # view_func  是将要调用的视图函数
#         # 这个函数返回None Django就会进行执行这个请求 (接着往下执行,包括执行视图，执行其他中间件的代码)
#         # 返回HttpResponse对象 django就不会返回调用相应的视图
#         try:
#             auth = get_authorization_header(request).split()
#
#             if not auth or auth[0].lower() != self.keyword.lower().encode():
#                 raise exceptions.ValidationError("请传入JWT!")
#
#             if len(auth) == 1:
#                 msg = "不可用的JWT请求头！"
#                 raise exceptions.AuthenticationFailed(msg)
#             elif len(auth) > 2:
#                 msg = '不可用的JWT请求头！JWT Token中间不应该有空格！'
#                 raise exceptions.AuthenticationFailed(msg)
#
#             try:
#                 jwt_token = auth[1]
#                 jwt_info = jwt.decode(jwt_token, settings.SECRET_KEY, algorithms='HS256')
#                 userid = jwt_info.get('userid')
#                 try:
#                     # 绑定当前user到request对象上
#                     user = OAUser.objects.get(pk=userid)
#                     # 这里的request对象是django 内置的
#                     request.user = user
#                     request.auth = jwt_token
#                     # setattr(request, 'user', user)
#                     # return user, jwt_token
#                 except:
#                     msg = '用户不存在！'
#                     raise exceptions.AuthenticationFailed(msg)
#             except ExpiredSignatureError:
#                 msg = "JWT Token已过期！"
#                 raise exceptions.AuthenticationFailed(msg)
#         except Exception as e:
#             print(e)
#             return JsonResponse(data={"detail": "请先登录！"}, status=HTTP_403_FORBIDDEN)

from django.utils.deprecation import MiddlewareMixin
from rest_framework.authentication import get_authorization_header
from rest_framework import exceptions
import jwt
from django.conf import settings
from django.contrib.auth import get_user_model
from django.http.response import JsonResponse
from rest_framework.status import HTTP_403_FORBIDDEN
from jwt.exceptions import ExpiredSignatureError
from django.contrib.auth.models import AnonymousUser
from django.urls import reverse

OAUser = get_user_model()

class LoginCheckMiddleware(MiddlewareMixin):
    keyword = "JWT"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 对于那些不需要登录就能访问的接口，可以写在这里
        # self.white_list = ['/auth/login']
        self.white_list = [reverse('oaauth:login'),reverse('stuff:active_staff')]

    def process_view(self, request, view_func, view_args, view_kwargs):
        # 1. 如果返回None，那么会正常执行（包括执行视图、执行其他中间件的代码）
        # 2. 如果返回一个HttpResponse对象，那么将不会执行视图，以及后面的中间件代码
        if request.path in self.white_list or request.path.startswith(settings.MEDIA_URL):
            request.user = AnonymousUser()
            request.auth = None
            return None

        try:
            auth = get_authorization_header(request).split()
            if not auth or auth[0].lower() != self.keyword.lower().encode():
                raise exceptions.ValidationError("请传入JWT！")

            if len(auth) == 1:
                msg = "不可用的JWT请求头！"
                raise exceptions.AuthenticationFailed(msg)
            elif len(auth) > 2:
                msg = '不可用的JWT请求头！JWT Token中间不应该有空格！'
                raise exceptions.AuthenticationFailed(msg)

            try:
                jwt_token = auth[1]
                jwt_info = jwt.decode(jwt_token, settings.SECRET_KEY, algorithms='HS256')
                userid = jwt_info.get('userid')
                try:
                    # 绑定当前user到request对象上
                    user = OAUser.objects.get(pk=userid)
                    # 这个request对象是HttpRequest对象：是Django内置的
                    request.user = user
                    request.auth = jwt_token
                except:
                    msg = '用户不存在！'
                    raise exceptions.AuthenticationFailed(msg)
            except ExpiredSignatureError:
                msg = "JWT Token已过期！"
                raise exceptions.AuthenticationFailed(msg)
        except Exception as e:
            print(e)
            return JsonResponse(data={"code":"888","detail": "请先登录！"}, status=HTTP_403_FORBIDDEN)